﻿/*
  Copyright © Alexander G. Bykin, Russia 2009-2010
  This source is subject to the Microsoft Public License (Ms-PL).
  Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
  All other rights reserved.
*/

namespace System.Windows.Controls.UnitTests
{
    using Microsoft.Silverlight.Testing;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Provides the framework for testing the <see cref="DataGroup"/>.
    /// </summary>
    public class DataGroupTestBase : SilverlightTest
    {
        #region Private Properties

        /// <summary>
        /// Holds whether the <see cref="DataGroup"/> has loaded.
        /// </summary>
        private bool isLoaded;

        #endregion

        #region Protected Properties

        /// <summary>
        /// Gets or sets the base <see cref="DataGroup"/> app.
        /// </summary>
        protected UserControl DataGroupAppBase { get; set; }

        #endregion

        #region TestInitialize

        [TestInitialize]
        public virtual void Initialize()
        {
        }

        #endregion

        #region TestCleanup

        [TestCleanup]
        public virtual void Cleanup()
        {
            this.RemoveFromPanel();
        }

        #endregion

        #region Private Methods

        private DataGroup GetDataGroup()
        {
            Assert.IsNotNull(this.DataGroupAppBase, "DataGroupAppBase must not be null.");
            DataGroup dataGroup = this.DataGroupAppBase.FindChildByName("dataGroup") as DataGroup;
            Assert.IsNotNull(dataGroup, "DataGroupAppBase must contain a DataGroup.");
            return dataGroup;
        }

        /// <summary>
        /// Handles a Loaded event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event args.</param>
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            this.isLoaded = true;
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// Get a template part.
        /// </summary>
        /// <param name="partName">The part name.</param>
        /// <typeparam name="T">The type of the template part to expect.</typeparam>
        /// <returns>The template part.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "Doing this would require a method per template part type, which is unnecessary.")]
        protected T GetTemplatePart<T>(string partName)
            where T : DependencyObject
        {
            return this.GetDataGroup().FindChildByName(partName) as T;
        }

        /// <summary>
        /// Add the <see cref="DataGroup"/> app to the panel and wait for the <see cref="DataGroup"/> to load.
        /// </summary>
        protected void AddToPanelAndWaitForLoad()
        {
            DataGroup dataGroup = null;

            this.EnqueueCallback(() =>
            {
                dataGroup = this.GetDataGroup();
                this.isLoaded = false;
                dataGroup.Loaded += new RoutedEventHandler(this.OnLoaded);
                this.TestPanel.Children.Add(this.DataGroupAppBase);
            });
            this.EnqueueConditional(() => this.isLoaded);
            this.EnqueueCallback(() => dataGroup.Loaded -= new RoutedEventHandler(this.OnLoaded));
        }

        /// <summary>
        /// Remove the <see cref="DataGroup"/> app from the panel, if it's been added.
        /// </summary>
        protected void RemoveFromPanel()
        {
            if (this.DataGroupAppBase != null && this.TestPanel.Children.Contains(this.DataGroupAppBase))
            {
                this.TestPanel.Children.Remove(this.DataGroupAppBase);
            }
        }

        #endregion
    }
}